using System;
using System.Collections.Generic;
using System.Windows.Forms;
using CommonGui;
using ClientApi;
using DevExpress.XtraEditors;
using DevExpress.XtraPrinting;
using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Nodes;

namespace RitaReports
{
    public partial class RitaReportsForm : BaseClientForm
    {
        #region Fields

        private readonly List<IRitaReport> _reports = new List<IRitaReport>();
        private readonly List<IRitaReport> _createdReports = new List<IRitaReport>();

        private bool _reportsListPopulated;

        #endregion
        
        #region Properties

        IRitaReport CurrentReport
        {
            get { return (listReports.FocusedNode != null) ? listReports.FocusedNode.Tag as IRitaReport : null; }
        }

        #endregion

        #region Constructors

        public RitaReportsForm(IEnumerable<IRitaReport> reports)
        {
            InitializeComponent();

            _reports.Clear();
            _createdReports.Clear();

            _reports.AddRange(reports);
            helpProvider1.HelpNamespace = HelpPathProvider.GetStringPathHelpFile();
        }

        #endregion

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);

            listReports.BeginUnboundLoad();
            listReports.Nodes.Clear();

            foreach (IRitaReport report in _reports)
            {
                AddReportToList(null, report);
            }

            listReports.FocusedNode = null;
            listReports.ExpandAll();
            listReports.EndUnboundLoad();

            _reportsListPopulated = true;
        }

        void AddReportToList(TreeListNode parent, IRitaReport report)
        {
            TreeListNode node = listReports.AppendNode(report, parent);

            node.SetValue(tlcReport, report.Name);
            node.StateImageIndex = 0;
            node.Tag = report;

            if (report.SubReports != null)
            {
                foreach (IRitaReport subReport in report.SubReports)
                {
                    AddReportToList(node, subReport);
                }
            }
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            UpdateReportViewer();
        }

        private void UpdateReportViewer()
        {
            IRitaReport report = this.CurrentReport;

            if (report != null && report.Viewer != null)
            {
                IReportFilterConditionds reportFilter = (report.Filter != null) ? report.Filter.FilterConditionds : null;

                report.UpdateDataSource(reportFilter, this);
                report.Viewer.UpdateReportViewer(report.DataSource);
            }

            UpdateReportMap();
        }

        private void UpdateReportMap()
        {
            IRitaReport report = this.CurrentReport;

            listDocMap.BeginUnboundLoad();
            listDocMap.ClearNodes();

            if (report != null && report.Viewer != null)
            {
                if (report.ReportMap != null && report.Viewer.XtraReportControl.Pages.First != null)
                {
                    AddBookmarksToList(report, report.Viewer.XtraReportControl.Pages.First.Document.BookmarkNodes, null);
                }
            }

            listDocMap.FocusedNode = null;
            listDocMap.EndUnboundLoad();
        }

        private void AddBookmarksToList(IRitaReport report, IBookmarkNodeCollection bookmarks, TreeListNode parent)
        {
            if (bookmarks != null)
            {
                foreach (BookmarkNode bookmark in bookmarks)
                {
                    TreeListNode node = listDocMap.AppendNode(bookmark, parent);


                    node.SetValue(tlcBookmark, report.ReportMap.GetBookmarkDisplayText(bookmark.Text));
                    node.Tag = bookmark;

                    AddBookmarksToList(report, bookmark.Nodes, node);
                }
            }
        }

        private void listDocMap_FocusedNodeChanged(object sender, FocusedNodeChangedEventArgs e)
        {
            if(e.Node != null)
            {
                BookmarkNode bookmark = (BookmarkNode)e.Node.Tag;

                reportViewer.SelectByBookmark(bookmark);
            }  
        }

        private void checkShowDocMap_CheckedChanged(object sender, EventArgs e)
        {
            splitControl.PanelVisibility = (checkShowDocMap.Checked)
                                               ? SplitPanelVisibility.Both
                                               : SplitPanelVisibility.Panel2;
        }

        private void listDocMap_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                TreeListHitInfo hi = listDocMap.CalcHitInfo(e.Location);
                IRitaReport report = this.CurrentReport;
                BookmarkNode bookmark = (hi.Node != null) ? (BookmarkNode)hi.Node.Tag : null;

                if (bookmark != null && report != null && report.ReportMap != null)
                {
                    report.ReportMap.ShowBookmarkDetails(report.DataSource, bookmark.Text, this);
                }
            }
        }

        private void listReports_FocusedNodeChanged(object sender, FocusedNodeChangedEventArgs e)
        {
            if (!_reportsListPopulated || this.DesignMode)
            {
                return;
            }

            IRitaReport report = this.CurrentReport;

            if (report != null && !_createdReports.Contains(report))
            {
                UpdateReportViewer();
                _createdReports.Add(report);
            }
            else
            {
                UpdateReportMap();
            }

            panelFilter.SuspendLayout();
            panelFilter.Controls.Clear();

            if (report != null && report.Filter != null && report.Filter.FilterControl != null)
            {
                report.Filter.FilterControl.Dock = DockStyle.Fill;
                panelFilter.Controls.Add(report.Filter.FilterControl);
            }
            panelFilter.ResumeLayout();

            reportViewer.Reports = (report != null && report.Viewer != null) ? report.Viewer.XtraReportControl : null;
            btnUpdate.Enabled = (report != null);
            checkShowDocMap.Enabled = (report != null && report.ReportMap != null);
            checkShowDocMap.Checked = (report != null && report.ReportMap != null);
        }
    }
}